using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Configuration;
using Newtonsoft.Json;

namespace SchoolPackage
{
    public partial class Default : System.Web.UI.Page
    {
        string logPath = HttpContext.Current.Server.MapPath("~/debug_file.txt");
        string connectionString = "Data Source=123.456.78.123;Initial Catalog=facedb;User ID=silicon;Password=YourPassword";
        string command = null;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(Request.Headers["dev_id"]))
            {
                HandleDeviceRequest();
            }
        }

        void HandleDeviceRequest()
        {
            var headers = Request.Headers;
            //string headerLog = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " => " +
            //                   string.Join("&", headers.AllKeys);
            string headerLog = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " => " +
                               string.Join("&", headers.AllKeys.Select(key => key + "=" + headers[key]));

            LogToFile(logPath, headerLog);

            string deviceId = headers["dev_id"];
            string blkNoStr = headers["blk_no"];
            string requestCode = headers["request_code"];

            int parsedDeviceId;
            if (!int.TryParse(deviceId, out parsedDeviceId))
            {
                LogToFile(logPath, "inside, deviceId is not a valid integer value");
                Response.Write("No valid dev_id found");
                Response.End();
                return;
            }
            LogToFile(logPath, "after, checking dev_id not found");

            SiliconData transData = null;
            //int blkNo = string.IsNullOrEmpty(blkNoStr) ? 0 : Convert.ToInt32(blkNoStr);
            try
            {
                transData = new SiliconData(deviceId);
            }
            catch (Exception ex)
            {
                string logPath = Server.MapPath("~/debug_error.txt");
                File.AppendAllText(logPath, "EXCEPTION: " + ex.Message + "\n" + ex.StackTrace);
            }
            LogToFile(logPath, "after, SiliconData class call");

            if (string.IsNullOrEmpty(headers["blk_no"]))
                headers["blk_no"] = "0"; // Assigning string "0"
            LogToFile(logPath, "Before if blk_no==0");
            if (headers["blk_no"] == "0")
            {
                LogToFile(logPath, "Entered, if (headers[\"blk_no\"] == \"0\")");
                Dictionary<string, object> inputValues = transData.Get(Request.InputStream);
                LogToFile(logPath, "Returned from Get");
                LogToFile(logPath, JsonConvert.SerializeObject(inputValues));

                if (requestCode == "realtime_glog")
                {
                    LogToFile(logPath, "entered, if (requestCode == \"realtime_glog\")");
                    InsertLogData(deviceId, inputValues);
                    LogToFile(logPath, "exit, if (requestCode == \"realtime_glog\")");
                }
                else if (requestCode == "receive_cmd")
                {
                    LogToFile(logPath, "entered, else if (requestCode == \"receive_cmd\")");

                    //SetDevice(deviceId, inputValues);
                    LogToFile(logPath, "exit, else if (requestCode == \"receive_cmd\")");

                }

                if (File.Exists(transData.AppendFile))
                    File.Delete(transData.AppendFile);
            }
            else
            {
                LogToFile(logPath, "Entered, else to append");
                transData.Append(Request.InputStream, Convert.ToInt32(headers["blk_no"]));
                LogToFile(logPath, "Exit, else to append");
            }

            //Dictionary<string, string> command = new Dictionary<string, string>
            //{
            //    { "response_code", "OK" }
            //};
            transData.Set(command, null, Response);
            LogToFile(logPath, command.ToString());
            LogToFile(logPath,  Response.ToString());
        }

        void LogToFile(string path, string content)
        {
            File.AppendAllText(path, content + Environment.NewLine);
        }

        void SetDevice(string deviceId, Dictionary<string, object> inputValues)
        {
            string note = JsonConvert.SerializeObject(inputValues);

            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();

                SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM device WHERE name = @deviceId", conn);
                cmd.Parameters.AddWithValue("@deviceId", deviceId);
                int count = (int)cmd.ExecuteScalar();

                string sql = (count > 0)
                    ? "UPDATE device SET note = @note, regtime = GETDATE() WHERE name = @deviceId"
                    : "INSERT INTO device (name, note, regtime) VALUES (@deviceId, @note, GETDATE())";

                cmd = new SqlCommand(sql, conn);
                cmd.Parameters.AddWithValue("@deviceId", deviceId);
                cmd.Parameters.AddWithValue("@note", note);
                cmd.ExecuteNonQuery();
            }
        }

        void InsertLogData(string deviceId, Dictionary<string, object> data)
        {
            if (!data.ContainsKey("user_id") || !data.ContainsKey("verify_mode") || !data.ContainsKey("io_time"))
                return;

            string OrgId = deviceId.Substring(0, 5);
            string machineId = deviceId.Substring(5, 2);
            string userId = data["user_id"].ToString();
            string ioTime = data["io_time"].ToString();

            string regTime = DateTime.ParseExact(ioTime, "yyyyMMddHHmmss", null).ToString("yyyy-MM-dd HH:mm:ss");

            string connStr = WebConfigurationManager.ConnectionStrings["schoolconnection"].ToString();
            using (SqlConnection con = new SqlConnection(connStr))
            {
                SqlCommand cmd = new SqlCommand("INSERT INTO tblattendance (OrgId, MachineId, empno, name, DateOfTransaction) " +
                                                "VALUES (@OrgId, @MachineId, @EmpNo, @Name, @DateOfTransaction)", con);
                cmd.Parameters.AddWithValue("@OrgId", OrgId);
                cmd.Parameters.AddWithValue("@MachineId", machineId);
                cmd.Parameters.AddWithValue("@EmpNo", userId);
                cmd.Parameters.AddWithValue("@Name", "");
                cmd.Parameters.AddWithValue("@DateOfTransaction", regTime);

                con.Open();
                cmd.ExecuteNonQuery();
            }
        }
    }
}
